﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyLambda
{
    public delegate void NoReturnNoParaOutClass();
    public delegate void GenericDelegate<T>();
    public class LambdaShow
    {
        public delegate void NoReturnNoPara();
        public delegate void NoReturnWithPara(int x, string y);//1 声明委托
        public delegate void NoReturnWithParaNew(int x);//1 声明委托
        public delegate int WithReturnNoPara();
        public delegate string WithReturnWithPara(out int x, ref int y);

        public void Show()
        {
            //Lambda前世今生；
            {
                //int i = 10;
                //.NetFramework1.0/1.1时代
                NoReturnNoPara method = new NoReturnNoPara(DoNothing);
                NoReturnWithPara noReturnWith = new NoReturnWithPara(Study);

            }
            //匿名方法
            //.NetFramework2.0  匿名方法  增加了一个delegate关键字,可以访问到除了参数以外的局部变量
            int i = 0;
            {
                NoReturnNoPara method = new NoReturnNoPara(delegate ()
                {
                    Console.WriteLine(i);
                    //如果要在这里调用变量j
                    Console.WriteLine("This is DoNothing");
                });
                NoReturnWithPara noReturnWith = new NoReturnWithPara(delegate (int id, string name)
                {
                    Console.WriteLine($"{id} {name} 学习.Net高级班");
                });
            }
            //.NetFramework3.0  去掉delegate关键了，在参数的后增加了一个=>  goes to
            {
                //=> goes to
                NoReturnWithPara noReturnWith = new NoReturnWithPara((int id, string name) =>
                {
                    Console.WriteLine($"{id} {name} 学习.Net高级班");
                });
            }
            //.NetFramework3.0 后期，去掉了匿名方法红的参数类型--为什么可以去掉？   
            {
                // ???Why？？？  因为指定给委托后； 编译器就按照委托的参数类型来匹配；根据委托的参数和返回值来推到出来，
                // 语法糖：编译器提供的便捷功能；
                NoReturnWithPara noReturnWith = new NoReturnWithPara((id, name) =>
                {
                    Console.WriteLine($"{id} {name} 学习.Net高级班");
                });
            }
            {
                ////如果匿名方法体中只有一行代码，可以省略方法体的大括号； 
                NoReturnWithPara noReturnWith = new NoReturnWithPara((id, name) => Console.WriteLine($"{id} {name} 学习.Net高级班"));

            }
            //一个参数的时候；如果只有一个参数---参数的小括号也可以省略掉
            {
                // NoReturnWithParaNew method = new NoReturnWithParaNew((id) => Console.WriteLine($"{id}   学习.Net高级班"));
                NoReturnWithParaNew method1 = new NoReturnWithParaNew(id => Console.WriteLine($"{id}   学习.Net高级班"));
                NoReturnWithParaNew method2 = id => Console.WriteLine($"{id}   学习.Net高级班");   //lambada表达式

                //Lambad 本质是什么？  委托（错误）？ 匿名方法？  方法？
                // 其实就是一个方法--匿名方法； 在底层的实现---lambad会生成一个<>c. 类， 在类里面会生成和lambad 表达式参数和返回值完全匹配的方法；
            }

            //方法返回值；
            //如果有返回值？ 如果lambda表达式中只有一行代码，且有返回值，可以省略return;
            {
                // Func<int,string> func1 = i => { return i.ToString(); };
                Func<int, string> func2 = i => i.ToString();

                Func<int> func4 = () => { return 1234; };
                Func<int> func3 = () => 1234;
            }
        }

        private void DoNothing()
        {
            //如果要在这里调用变量j
            Console.WriteLine("This is DoNothing");
        }

        private void Study(int id, string name)
        {
            Console.WriteLine($"{id} {name} 学习.Net高级班");
        }
    }
}
